
#ifndef _SYMBOLDEFINE_H
#define _SYMBOLDEFINE_H
#include <iostream>
#include <string>
#include <list>
#include "absyn.h"
using namespace std;

/* three type kind
 * type_decl ： simple_type_decl  |  array_type_decl  |  record_type_decl
 */

//simple type
class SimpleType {
public:
	string name;	// 类型名称
	int type;		// 实际数据类型
	bool isVar;		// true: 变量，false: 常量
	
	SimpleType():name("undifined"){}
	SimpleType(string name, int type, bool isVar):name(name),type(type),isVar(isVar){}
};

// array index 
class SubBoundDefinition {
    public:
	int boundType;				// 数组下标类型
	Object LowerBound;			// 下标范围
	Object UpperBound;			// --

	SubBoundDefinition(){}
	SubBoundDefinition(int boundType, Object lowerBound, Object upperBound) {
		this->boundType = boundType;
		LowerBound = lowerBound;
		UpperBound = upperBound;
	}
};

class RecordDefinition;
//array type
class ArrayDefinition
{
    public:
	int arrayType;					// 数组元素类型
	SubBoundDefinition subBound;	// 下标范围

	ArrayDefinition(){}
	ArrayDefinition(int arrayType, int boundType, Object upper, Object lower)
	{
		this->arrayType = arrayType;
		this->subBound = SubBoundDefinition(boundType, upper, lower);
	}
};

//record
enum RecordType
{
    ANONYMOUS = 72,	
	DEFINED = 73	
};
//record look up return
class LookupReturn
{
public:
	int totalOff;	// 总偏移量
	int jumpLevel;	// 跨越的层级
	int type;		// 数据的类型

	LookupReturn(){}
	LookupReturn(int totalOff, int jumpLevel, int type)
	{
		this->totalOff = totalOff;
		this->jumpLevel = jumpLevel;
		this->type = type;
	}
};
//record definition
class TypeDefinition;
class RecordDefinition 
{
    public:
	RecordType type;			// record类型
	list<TypeDefinition> ptr;	// record的域（成员变量）

	RecordDefinition(){}
	RecordDefinition(RecordType type, list<TypeDefinition> ptr):type(type),ptr(ptr){}
};


/* four symboltable format
 * 1 variable
 * 2 type
 * 3 function
 * 4 procedure
 */

//memory position
//used for mark the data offset
class MemPos 
{
public:
    int basePos;	// 基地址
    int offset;		// 偏移量
	MemPos(){}
    MemPos(int basePos, int offset):basePos(basePos),offset(offset){}
};

// variable
class VariableDefinition 
{
public:
	string name;			// 变量名
	int type;				// 变量类型
	bool isConst;			// true：常量，false：变量
	int nestLevel;			// 层级
	Object pAttr;			// 值
	MemPos memPos;			// 地址（偏移量）
    VariableDefinition():name("undefined"){}
	VariableDefinition(string name, int type, bool isConst, int nestLevel, Object pAttr, int offset) {
		this->name = name;
		this->type = type;
		this->isConst = isConst;
		this->nestLevel = nestLevel;
		this->pAttr = pAttr;
		this->memPos = MemPos(0, offset);
	}
};

//type
class TypeDefinition
{
public:
	string name;			// 类型名
	int type;				// 实际类型
	int nestLevel;			// 层级
	struct Object pAttr;	// 值
	int size;				// 一个该类型变量占用空间大小

	TypeDefinition():name("undefined"){}
	TypeDefinition(string name):name(name){}
	TypeDefinition(string name, int type, int nestLevel, struct Object pAttr, int size)
	{
		this->name = name;
		this->type = type;
		this->nestLevel = nestLevel;
		this->pAttr = pAttr;
		this->size = size;
	}

};

//function
class FunctionDefinition
{
public:
	string name;				// 函数名
	list<SimpleType> paraList;	// 参数类型列表
	int retType; 				// 返回值类型
	int nestLevel; 				// 层级
	FunctionDefinition():name("undefined"){}
	FunctionDefinition(string name, list<SimpleType> paraList, int retType, int nestLevel)
	{
		this->name = name;
		this->paraList = paraList;
		this->retType = retType;
		this->nestLevel = nestLevel;
	}
};

//procedure
class ProcedureDefinition
{
public:
	string name;	// 过程名
	list<SimpleType> paraList;	// 参数类型列表
	int nestLevel; 	// 层级
	ProcedureDefinition():name("undefined"){}
	ProcedureDefinition(string name, list<SimpleType> paraList, int nestLevel)
	{
		this->name = name;
		this->paraList = paraList;
		this->nestLevel = nestLevel;
	}
};

#endif
